<template>
    <view @tap="backToTop" class="u-back-top" :class="['u-back-top--mode--' + mode]" :style="[{
        bottom: bottom + 'rpx',
        right: right + 'rpx',
        borderRadius: mode == 'circle' ? '10000rpx' : '8rpx',
        zIndex: uZIndex,
        opacity: opacity
    }, customStyle]">
        <view class="u-back-top__content" v-if="!$slots.default && !$slots.$default">
            <u-icon @click="backToTop" :name="icon" :custom-style="iconStyle"></u-icon>
            <view class="u-back-top__content__tips">
                {{tips}}
            </view>
        </view>
        <slot v-else />
    </view>
</template>

<script>
    export default {
        name: 'u-back-top',
        props: {
            // 返回顶部的形状，circle-圆形，square-方形
            mode: {
                type: String,
                default: 'circle'
            },
            // 自定义图标
            icon: {
                type: String,
                default: 'arrow-upward'
            },
            // 提示文字
            tips: {
                type: String,
                default: ''
            },
            // 返回顶部滚动时间
            duration: {
                type: [Number, String],
                default: 100
            },
            // 滚动距离
            scrollTop: {
                type: [Number, String],
                default: 0
            },
            // 距离顶部多少距离显示，单位rpx
            top: {
                type: [Number, String],
                default: 400
            },
            // 返回顶部按钮到底部的距离，单位rpx
            bottom: {
                type: [Number, String],
                default: 200
            },
            // 返回顶部按钮到右边的距离，单位rpx
            right: {
                type: [Number, String],
                default: 40
            },
            // 层级
            zIndex: {
                type: [Number, String],
                default: '9'
            },
            // 图标的样式，对象形式
            iconStyle: {
                type: Object,
                default() {
                    return {
                        color: '#909399',
                        fontSize: '38rpx'
                    }
                }
            },
            // 整个组件的样式
            customStyle: {
                type: Object,
                default() {
                    return {}
                }
            }
        },
        watch: {
            showBackTop(nVal, oVal) {
                // 当组件的显示与隐藏状态发生跳变时，修改组件的层级和不透明度
                // 让组件有显示和消失的动画效果，如果用v-if控制组件状态，将无设置动画效果
                if(nVal) {
                    this.uZIndex = this.zIndex;
                    this.opacity = 1;
                } else {
                    this.uZIndex = -1;
                    this.opacity = 0;
                }
            }
        },
        computed: {
            showBackTop() {
                // 由于scrollTop为页面的滚动距离，默认为px单位，这里将用于传入的top(rpx)值
                // 转为px用于比较，如果滚动条到顶的距离大于设定的距离，就显示返回顶部的按钮
                return this.scrollTop > uni.upx2px(this.top);
            },
        },
        data() {
            return {
                // 不透明度，为了让组件有一个显示和隐藏的过渡动画
                opacity: 0,
                // 组件的z-index值，隐藏时设置为-1，就会看不到
                uZIndex: -1
            }
        },
        methods: {
            backToTop() {
                uni.pageScrollTo({
                    scrollTop: 0,
                    duration: this.duration
                });
            }
        }
    }
</script>

<style lang="scss" scoped>
    @import "../../libs/css/style.components.scss";
    
    .u-back-top {
        width: 80rpx;
        height: 80rpx;
        position: fixed;
        z-index: 9;
        @include vue-flex;
        flex-direction: column;
        justify-content: center;
        background-color: #E1E1E1;
        color: $u-content-color;
        align-items: center;
        transition: opacity 0.4s;
        
        &__content {
            @include vue-flex;
            flex-direction: column;
            align-items: center;
            
            &__tips {
                font-size: 24rpx;
                transform: scale(0.8);
                line-height: 1;
            }
        }
    }
</style>
